package at.fhj.itm11.forum.beans;

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpSession;

import org.primefaces.model.UploadedFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import at.fhj.itm11.forum.service.PostService;
import at.fhj.itm11.forum.service.RatingService;
import at.fhj.itm11.forum.service.TopicService;
import at.fhj.itm11.forum.service.dtos.PostDTO;
import at.fhj.itm11.forum.service.dtos.TopicDTO;
import at.fhj.itm11.forum.service.dtos.UserDTO;
import at.fhj.itm11.forum.util.ForumConstants;

@ManagedBean
@ViewScoped
public class PostBean implements Serializable {

	private static final long serialVersionUID = -8433063884320342294L;

	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Inject
	@Named("topicServiceImpl")
	private TopicService topicService;

	@Inject
	@Named("topicBean")
	private TopicBean topicBean;

	@Inject
	@Named("ratingServiceImpl")
	private RatingService ratingService;

	@Inject
	@Named("authenticationBean")
	private AuthenticationBean authBean;

	@Inject
	@Named("postServiceImpl")
	private PostService postService;

	private DataModel<PostDTO> postModel;

	private List<PostDTO> posts;
	private TopicDTO topic;
	private UserDTO user;

	private String title;
	private String text;
	private UploadedFile image;
	private UploadedFile video;
	
	private FacesContext facesContext;
	private ExternalContext externalContext;
	private HttpSession session;

	@PostConstruct
	public void init() {
		externalContext = FacesContext.getCurrentInstance().getExternalContext();
		session = authBean.getSession();
		
		initData();
	}

	public void initData() {
		String topicIdString = externalContext.getRequestParameterMap().get("id");
		if (topicIdString != null) {
			Long topicId = Long.valueOf(topicIdString);

			TopicDTO currentTopic = topicService.findById(topicId);

			if (currentTopic != null) {
				topicBean.setCurrentTopic(currentTopic);
				posts = loadPosts(currentTopic);
			}

			postModel = new ListDataModel<PostDTO>(posts);
		}
	}

	public List<PostDTO> loadPosts(TopicDTO topic) {
		this.setTopic(topic);
		posts = postService.getPostsByTopicId(topic.getId());
		user = (UserDTO) session.getAttribute(
				ForumConstants.SESSION_CURRENT_USER);
		session.setAttribute(
				ForumConstants.SESSION_CURRENT_TOPIC, topic);
		return posts;
	}

	public String register() {
		if (facesContext == null) {
			facesContext = FacesContext.getCurrentInstance();
		}
		
		try {
			Long topicId = postService.addPost(title, text, image, video,
					topicBean.getCurrentTopic(), authBean.getCurrentUser());

			facesContext.addMessage(null, new FacesMessage(
					FacesMessage.SEVERITY_INFO, "Post creation successful!",
					"Creation successful"));

			return "showPosts?faces-redirect=true&id=" + topicId;
		} catch (Exception e) {
			String msg = null;

			if (e instanceof IllegalArgumentException) {
				msg = e.getMessage();
			} else if (e.getCause() instanceof IllegalArgumentException) {
				msg = e.getCause().getMessage();
			}

			if (PostService.EXCEPTION_TITLE_EMPTY.equals(msg)) {
				facesContext.addMessage("addPost:title", new FacesMessage(
						FacesMessage.SEVERITY_ERROR, "Creation failed",
						"Title must not be empty!"));
			} else if (PostService.EXCEPTION_TEXT_EMPTY.equals(msg)) {
				facesContext.addMessage("addPost:text", new FacesMessage(
						FacesMessage.SEVERITY_ERROR, "Creation failed",
						"Text must not be empty!"));
			} else if (PostService.EXCEPTION_ONLY_IMAGES.equals(msg)) {
				facesContext.addMessage("addPost:image", new FacesMessage(
						FacesMessage.SEVERITY_ERROR, "Creation failed",
						"Only images are allowed!"));
			} else if (PostService.EXCEPTION_ONLY_VIDEOS.equals(msg)) {
				facesContext.addMessage("addPost:video", new FacesMessage(
						FacesMessage.SEVERITY_ERROR, "Creation failed",
						"Only videos are allowed!"));
			} else {
				logger.error("registration failed", e);
				facesContext.addMessage(null, new FacesMessage(
						FacesMessage.SEVERITY_ERROR, "Creation failed",
						"Creation failed"));
			}
		}

		return null;
	}

	public UploadedFile getImage() {
		return image;
	}

	public void setImage(UploadedFile image) {
		this.image = image;
	}

	public UploadedFile getVideo() {
		return video;
	}

	public void setVideo(UploadedFile video) {
		this.video = video;
	}

	public List<PostDTO> getPosts() {
		return posts;
	}

	public void setPosts(List<PostDTO> posts) {
		this.posts = posts;
	}

	public TopicDTO getTopic() {
		return topic;
	}

	public void setTopic(TopicDTO topic) {
		this.topic = topic;
	}

	public UserDTO getUser() {
		return user;
	}

	public void setUser(UserDTO user) {
		this.user = user;
	}

	public DataModel<PostDTO> getPostModel() {
		return postModel;
	}

	public void setPostModel(DataModel<PostDTO> postModel) {
		this.postModel = postModel;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}
	
	public void setFacesContext(FacesContext facesContext) {
		this.facesContext = facesContext;
	}

	public void setExternalContext(ExternalContext externalContext) {
		this.externalContext = externalContext;
	}
	
	public void setTopicService(TopicService topicService) {
		this.topicService = topicService;
	}
	
	public void setPostService(PostService postService) {
		this.postService = postService;
	}
	
	public void setTopicBean(TopicBean topicBean) {
		this.topicBean = topicBean;
	}
	
	public void setAuthBean(AuthenticationBean authBean) {
		this.authBean = authBean;
	}
	
	public void setSession(HttpSession session) {
		this.session = session;
	}

}
